package jumpingnotes.service.remoting;
import java.util.Date;
import java.util.List;
import java.util.Set;

import jumpingnotes.model.*;
import jumpingnotes.model.entity.*;
public class FriendServiceImpl extends GenericService implements FriendService {
	
	public Result friendInvite(String memberIDTo, String memberIDFrom)
	{
		Member memberFrom = accessService.findMemberById(Integer.parseInt(memberIDFrom));
		if(memberFrom == null)
			return new Result(ErrorType.USER_NOT_EXIST);
		Member memberTo = accessService.findMemberById(Integer.parseInt(memberIDTo));
		if(memberTo == null)
			return new Result(ErrorType.USER_NOT_EXIST);
		
		// check invitation state
		Set<Friend> s1 = memberFrom.getFriendsForMemberIdFrom();
		// friend relationship exists
		if(s1 != null && s1.size() >= 1)
		{
			for(Friend friend : s1)
				if(friend.getMemberByMemberIdTo().getMemberId().equals(Integer.parseInt(memberIDTo)))
					return new Result(ErrorType.FRIEND_EXIST);
		}
			
		Set<FriendConfirm> s2 = memberFrom.getFriendConfirmsForMemberIdFrom();
		// friend relationship has not been confirmed
		if(s2 != null && s2.size() >= 1)
		{
			for(FriendConfirm friendConfirm : s2)
			{
				if(friendConfirm.getMemberByMemberIdTo().getMemberId().equals(Integer.parseInt(memberIDTo)))
				return new Result(ErrorType.FRIEND_NOT_CONFIRM);
			}
		}

		FriendConfirm friendConfirm = new FriendConfirm();
		friendConfirm.setCreateTime(new Date());
		friendConfirm.setMemberByMemberIdFrom(memberFrom);
		friendConfirm.setMemberByMemberIdTo(memberTo);
		// the format of the message?
		friendConfirm.setMessage("");
		accessService.saveFriendConfirm(friendConfirm);
		return new Result(friendConfirm.getFriendConfirmId());
	}
	
	public Result friendInviteConfirm(String memberIDTo, String friendConfirmID)
	{
		FriendConfirm friendConfirm = accessService.findFriendConfirmById(Integer.parseInt(friendConfirmID));
		// check
		if(friendConfirm != null)
		{
			if(friendConfirm.getMemberByMemberIdTo().getMemberId().equals(new Integer(memberIDTo)))
			{
				Friend friend = new Friend();
				friend.setCreateTime(new Date());
				friend.setMemberByMemberIdFrom(friendConfirm.getMemberByMemberIdFrom());
				friend.setMemberByMemberIdTo(friendConfirm.getMemberByMemberIdTo());
				accessService.saveFriend(friend);
				Friend friend2 = new Friend();
				friend2.setCreateTime(new Date());
				friend2.setMemberByMemberIdFrom(friendConfirm.getMemberByMemberIdTo());
				friend2.setMemberByMemberIdTo(friendConfirm.getMemberByMemberIdFrom());
				accessService.saveFriend(friend2);
				accessService.deleteFriendConfirm(friendConfirm);
				
				Member member = friendConfirm.getMemberByMemberIdFrom();
				ActivityTemplateParam[] activityParams = new ActivityTemplateParam[1];
				activityParams[0] = new ActivityTemplateParam();
				activityParams[0].setName("member");
				activityParams[0].setValue(member.getMemberId() + "&" + member.getNickName());
				memberActivityCreate(member.getMemberId().toString(), ActivityType.FRIEND_RELATION_CREATE, activityParams, null, null, "1");								
				member = friendConfirm.getMemberByMemberIdTo();
				ActivityTemplateParam[] activityParams2 = new ActivityTemplateParam[1];
				activityParams2[0] = new ActivityTemplateParam();
				activityParams2[0].setName("member");
				activityParams2[0].setValue(member.getMemberId() + "&" + member.getNickName());
				memberActivityCreate(member.getMemberId().toString(), ActivityType.FRIEND_RELATION_CREATE, activityParams2, null, null, "1");								
				
				return new Result();
			}
			else
				return new Result(ErrorType.INVALID_FRIEND_CONFIRM);
		}
		else
			return new Result(ErrorType.FRIEND_CONFIRM_NOT_EXIST);
	}
	
	public Result friendInviteDelete(String memberIDTo, String friendConfirmID)
	{
		FriendConfirm friendConfirm = accessService.findFriendConfirmById(Integer.parseInt(friendConfirmID));
		// check
		if(friendConfirm != null)
		{
			if(friendConfirm.getMemberByMemberIdTo().getMemberId().equals(new Integer(memberIDTo)))
			{
				accessService.deleteFriendConfirm(friendConfirm);
				return new Result();
			}
			else
				return new Result(ErrorType.INVALID_FRIEND_INVITE_DELETE);
		}
		else
			return new Result(ErrorType.FRIEND_CONFIRM_NOT_EXIST);
	}
	
	public Result friendDelete(String memberIDTo, String memberIDFrom)
	{
		Result result = doFriendDelete(memberIDTo, memberIDFrom);
		if (result.getReturnCode() == 0) {
			result = doFriendDelete(memberIDFrom, memberIDTo);
		} 
		return result;
	}

	private Result doFriendDelete(String memberIDTo, String memberIDFrom) {
		Member memberFrom = accessService.findMemberById(Integer.parseInt(memberIDFrom));
		if(memberFrom == null)
			return new Result(ErrorType.USER_NOT_EXIST);
		Member memberTo = accessService.findMemberById(Integer.parseInt(memberIDTo));
		if(memberTo == null)
			return new Result(ErrorType.USER_NOT_EXIST);
		Set<Friend> friendSet = memberFrom.getFriendsForMemberIdFrom();
		if(friendSet != null && friendSet.size()>0)
		{
    		for(Friend friend : friendSet)
    		if(friend.getMemberByMemberIdTo().getMemberId().equals(memberTo.getMemberId()))		
    		{
    			friendSet.remove(friend);
    			accessService.deleteFriend(friend);
    		}
		}
		return new Result();		
	}
	
	@Override
	public Result isFriend(String memberIDTo, String memberIDFrom) {
		// TODO Auto-generated method stub
		Member memberTo = accessService.findMemberById(Integer.parseInt(memberIDTo));
		Member memberFrom = accessService.findMemberById(Integer.parseInt(memberIDFrom));
		if (memberTo == null || memberFrom == null) {
			return new Result(ErrorType.USER_NOT_EXIST);
		}
		
		return new Result(queryService.isFriend(Integer.parseInt(memberIDTo), Integer.parseInt(memberIDFrom)));
	}

	@Override
	public Result friendInviteByEmail(String memberToEmail, String memberIDFrom) {
		// TODO Auto-generated method stub
		Result result = new Result(ErrorType.NO_ERROR);
		Member exampleMember = new Member();
		exampleMember.setEmail(memberToEmail);
		List<Member> memberList = accessService.findAllMember(exampleMember);
	
		Member memberTo = memberList.get(0);
		if (memberTo == null) {
			// TODO: Send invitation email
			
		} else {
			result = friendInvite(memberTo.getMemberId().toString(), memberIDFrom);
		}		
		return result;
	}
}
